<template>
  <div class="publish">
    <div class="page-header" v-if="!asModal">
      <div class="header-top">
        <button class="back-btn" @click="$router.back()">← 返回</button>
        <h1>发布动态</h1>
        <div class="header-actions">
          <button class="cancel-btn" @click="cancelPublish">取消</button>
          <button class="publish-btn" @click="publishPost">发布</button>
        </div>
      </div>
    </div>
    
    <div class="publish-content">
      <div class="publish-card" :class="{ minimal: asModal }">
        <div class="user-section" v-if="!asModal">
          <div class="user-avatar">👤</div>
          <div class="user-info">
            <h3>用户名</h3>
            <p>环保爱好者</p>
          </div>
        </div>
        
        <div class="editor-section">
          <EmojiTextarea
            v-model="postContent"
            placeholder="分享你的环保生活，记录此刻..."
            :rows="6"
            :maxlength="1000"
            :showCounter="!asModal"
            :showFooter="false"
            :showEmojiButton="false"
            :minimal="asModal"
            class="content-input-wrapper"
          />
          <div class="input-toolbar" v-if="!asModal">
            <button class="ai-polish-btn" @click="polishContent" :disabled="polishing">AI润色</button>
          </div>
          <!-- 样式已移至组件底部的主样式块 -->
          
          <div class="image-upload-section" v-if="asModal ? (imagePreviews.length > 0 || showImageGrid) : true">
            <div class="upload-progress-container" v-if="isUploading && uploadProgress > 0">
              <div class="progress-bar">
                <div class="progress-fill" :style="{ width: Math.min(uploadProgress, 100) + '%' }"></div>
              </div>
              <span class="progress-text">{{ Math.min(Math.round(uploadProgress), 100) }}%</span>
            </div>

            <div class="image-grid">
              <div class="grid-item" v-for="(preview, index) in imagePreviews" :key="index">
                <img :src="preview" alt="预览图片" />
                <button class="remove-badge" @click="removeImage(index)">×</button>
              </div>
              <button class="upload-tile" v-if="imagePreviews.length < 9" @click="triggerFileInput" aria-label="添加图片">
                <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                  <path d="M12 5v14M5 12h14" stroke="#9AA1A9" stroke-width="2" stroke-linecap="round"/>
                </svg>
                <input type="file" ref="fileInput" @change="handleImageUpload" accept="image/*" multiple style="display:none;" />
              </button>
            </div>
          </div>
        </div>
        
        <!-- 地点标签展示区 -->
        <div class="location-tags-container" v-if="selectedLocation">
          <div class="location-tag">
            <span class="location-tag-icon">📍</span>
            <span class="location-tag-text">{{ formatLocationTag(selectedLocation) }}</span>
            <button class="location-tag-remove" @click="removeLocation">×</button>
          </div>
        </div>
        
        
        
        <div class="additional-options">
          <div class="option-item">
            <label class="switch">
              <input type="checkbox" v-model="showLocation" @change="onToggleLocation">
              <span class="slider"></span>
            </label>
            <span class="option-label">显示位置</span>
          </div>
        </div>
        
        <!-- 标签选择器 -->
        <div class="tag-selector" v-if="showTagSelector">
          <h3>选择标签</h3>
          <div class="tag-input">
            <input 
              type="text" 
              v-model="newTag" 
              placeholder="输入新标签" 
              @keyup.enter="addTag"
            />
            <button @click="addTag">添加</button>
          </div>
          <div class="tag-list">
            <div 
              class="tag-item" 
              v-for="tag in availableTags" 
              :key="tag.name"
              :class="{ selected: selectedTags.includes(tag.name) }"
              @click="toggleTag(tag.name)"
            >
              {{ tag.name }} ({{ tag.post_count }})
            </div>
          </div>
          <div class="selected-tags" v-if="selectedTags.length > 0">
            <h4>已选择的标签：</h4>
            <div class="tag-pills">
              <span 
                class="tag-pill" 
                v-for="tag in selectedTags" 
                :key="tag"
              >
                {{ tag }}
                <button @click="removeTag(tag)">×</button>
              </span>
            </div>
          </div>
        </div>
        
        <!-- 位置预览 -->
        <div v-if="showLocation && locationPreview" class="location-preview">
          <i class="location-icon">📍</i>
          <span class="location-text">{{ locationPreview }}</span>
          <button class="remove-location-btn" @click="removeLocation">×</button>
        </div>
        
        <!-- 地点选择器 -->
        <LocationPicker
          :is-visible="showLocationPicker"
          @select="handleLocationSelect"
          @close="showLocationPicker = false"
        />
      </div>
    </div>

    <div v-if="asModal" class="modal-toolbar" role="toolbar">
      <div class="toolbar-left">
        <button class="tool-btn" title="图片" @click="showImageGrid = true">
          <svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
            <rect x="3" y="5" width="18" height="14" rx="2" stroke="currentColor" stroke-width="1.6"/>
            <path d="M8 12l3 3 4-5 4 6" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
            <circle cx="8" cy="9" r="1.5" fill="currentColor"/>
          </svg>
        </button>
        <button class="tool-btn" title="表情" @click="/* 预留 */ void 0">
          <svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
            <circle cx="12" cy="12" r="9" stroke="currentColor" stroke-width="1.6"/>
            <circle cx="9" cy="10" r="1.2" fill="currentColor"/>
            <circle cx="15" cy="10" r="1.2" fill="currentColor"/>
            <path d="M8 15c1.2 1 2.6 1.5 4 1.5s2.8-.5 4-1.5" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/>
          </svg>
        </button>
        <button class="tool-btn" title="话题" @click="showTagSelector = !showTagSelector">
          <svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
            <path d="M9 4l-2 16M17 4l-2 16M4 9h16M3 15h16" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/>
          </svg>
        </button>
        <button class="tool-btn" title="定位" @click="showLocationPicker = true">
          <svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
            <path d="M12 21s7-6.2 7-11a7 7 0 10-14 0c0 4.8 7 11 7 11z" stroke="currentColor" stroke-width="1.6" fill="none"/>
            <circle cx="12" cy="10" r="2.5" stroke="currentColor" stroke-width="1.6"/>
          </svg>
        </button>
        <button class="ai-text-btn" @click="polishContent" :disabled="polishing" title="AI 润色">
          ✨ AI 润色
        </button>
      </div>
      <div class="toolbar-right">
        <span class="char-count">{{ postContent.length }} 字</span>
        <button class="modal-publish" @click="publishPost">发布</button>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
const props = defineProps<{ asModal?: boolean }>()
const emit = defineEmits<{ (e: 'published'): void; (e: 'close'): void }>()
import { ref, onMounted, watch, inject } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import EmojiTextarea from '@/components/EmojiTextarea.vue'
import LocationPicker from '@/components/LocationPicker.vue'
import { createPost, uploadPostImages, getTags, polishPostText } from '@/api/community'
import request from '../utls/require'
import { addLocationTag, removeLocationTag, formatLocationTag } from '@/utils/locationUtils.js'
const triggerPointsToast = inject<(delta: number) => void>('triggerPointsToast')

// 获取路由参数
const route = useRoute()
const router = useRouter()

const showMessage = (message: string, type: 'success' | 'error' = 'success') => {
  const toast = document.createElement('div')
  toast.textContent = message
  const base = 'position:fixed;left:50%;bottom:80px;transform:translateX(-50%);padding:10px 16px;border-radius:10px;color:#fff;box-shadow:0 6px 20px rgba(0,0,0,0.25);z-index:9999;font-size:14px;opacity:0.95;'
  const bg = type === 'success' ? 'background:#2E8B57;' : 'background:#E74C3C;'
  toast.setAttribute('style', base + bg)
  document.body.appendChild(toast)
  setTimeout(() => {
    toast.style.transition = 'opacity 0.3s ease'
    toast.style.opacity = '0'
    setTimeout(() => { toast.remove() }, 300)
  }, 1800)
}

const emitClose = () => { emit('close') }

// 帖子内容
const postContent = ref('')

// 图片相关
const fileInput = ref<HTMLInputElement | null>(null)
const imagePreviews = ref<string[]>([])
const imageFiles = ref<File[]>([])
const uploadProgress = ref<number>(0)
const isUploading = ref<boolean>(false)

const polishing = ref(false)
const showImageGrid = ref(false)

// 触发文件选择
const triggerFileInput = () => {
  if (fileInput.value) {
    fileInput.value.click()
  }
}

// 处理图片上传
const handleImageUpload = (event: Event) => {
  const input = event.target as HTMLInputElement
  if (!input.files || input.files.length === 0) return

  const files = Array.from(input.files)
  const totalImages = imagePreviews.value.length + files.length

  if (totalImages > 9) {
    showMessage('最多只能上传9张图片','error')
    return
  }

  // 验证文件大小和类型
  const allowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp']
  const maxSize = 10 * 1024 * 1024 // 10MB
  const validFiles = []
  
  for (const file of files) {
    if (!allowedTypes.includes(file.type)) {
      showMessage(`文件 ${file.name} 格式不支持，仅支持JPG、PNG、GIF和WebP格式`,'error')
      continue
    }
    if (file.size > maxSize) {
      showMessage(`文件 ${file.name} 大小超过10MB限制`,'error')
      continue
    }
    validFiles.push(file)
  }

  // 生成预览
  validFiles.forEach(file => {
    const reader = new FileReader()
    reader.onload = (e) => {
      if (e.target?.result) {
        imagePreviews.value.push(e.target.result as string)
        imageFiles.value.push(file)
      }
    }
    reader.onerror = () => {
      showMessage(`文件 ${file.name} 读取失败`,'error')
    }
    reader.readAsDataURL(file)
  })

  // 清空input值，允许重复选择同一文件
  input.value = ''
}

// 移除图片
const removeImage = (index: number) => {
  imagePreviews.value.splice(index, 1)
  imageFiles.value.splice(index, 1)
}

const showTagSelector = ref(false)
const newTag = ref('')
const availableTags = ref<{ name: string; post_count: number }[]>([])
const selectedTags = ref<string[]>([])

const loadTags = async () => {
  try {
    const resp = await getTags()
    const list = resp?.data?.tags || []
    availableTags.value = Array.isArray(list) ? list : []
  } catch (_) {}
}

const addTag = () => {
  const name = newTag.value.trim()
  if (!name) return
  if (!selectedTags.value.includes(name)) {
    selectedTags.value.push(name)
  }
  newTag.value = ''
}

const toggleTag = (name: string) => {
  const i = selectedTags.value.indexOf(name)
  if (i > -1) {
    selectedTags.value.splice(i, 1)
  } else {
    selectedTags.value.push(name)
  }
}

const removeTag = (name: string) => {
  const i = selectedTags.value.indexOf(name)
  if (i > -1) selectedTags.value.splice(i, 1)
}

// 上传图片到服务器 - 分批上传以提高成功率
const uploadImages = async () => {
  if (imageFiles.value.length === 0) {
    return []
  }

  try {
    // 重置上传状态
    uploadProgress.value = 0
    isUploading.value = true
    
    // 分批上传，每次最多3张
    const batchSize = 3
    const imageUrls = []
    
    for (let i = 0; i < imageFiles.value.length; i += batchSize) {
      const batch = imageFiles.value.slice(i, i + batchSize)
      const formData = new FormData()
      
      batch.forEach(file => {
        formData.append('images', file)
      })

      console.log(`[Publish] 正在上传第 ${i+1}-${Math.min(i+batchSize, imageFiles.value.length)} 张图片`)
      // 定义进度回调函数（progress: 0-100，表示当前批次上传百分比）
      const handleProgress = (progress: number) => {
        const total = imageFiles.value.length
        const completed = i
        const currentBatchCount = batch.length
        const batchFraction = (Math.max(0, Math.min(progress, 100)) / 100) * currentBatchCount
        const overall = ((completed + batchFraction) / total) * 100
        uploadProgress.value = Math.max(0, Math.min(overall, 100))
      }

      const response = await uploadPostImages(formData, handleProgress)
      console.log('[Publish] 图片批次上传成功', response)
      
      // 提取图片URL数组
      let batchUrls = []
      if (response.data?.data?.image_urls && Array.isArray(response.data.data.image_urls)) {
        batchUrls = response.data.data.image_urls
      } else if (response.data?.image_urls && Array.isArray(response.data.image_urls)) {
        batchUrls = response.data.image_urls
      }
      
      if (batchUrls.length > 0) {
        imageUrls.push(...batchUrls)
      }
    }
    
    return imageUrls
  } catch (error) {
    console.error('[Publish] 图片上传失败:', error)
    // 提供更详细的错误信息
    const errorMessage = error instanceof Error ? error.message : '图片上传失败'
    showMessage(`图片上传失败: ${errorMessage}`,'error')
    throw error
  } finally {
    // 无论成功失败，都重置上传状态
    isUploading.value = false
    uploadProgress.value = 0
  }
}

const showLocation = ref(false)
const geo = ref<{ lat: number; lng: number } | null>(null)
const locationPreview = ref('')
const locationInfo = ref<any | null>(null)

let reverseServiceDown = false

const getBrowserLocation = () => {
  if (!navigator.geolocation) return
  navigator.geolocation.getCurrentPosition(
    (pos) => {
      const { latitude, longitude } = pos.coords
      geo.value = { lat: latitude, lng: longitude }
      if (showLocation.value) reverseGeocode()
    },
    (err) => {
      console.warn('[Publish] 浏览器定位失败', err)
      locationPreview.value = '定位失败，请选择地点'
    }
  )
}

async function reverseGeocode() {
  if (!geo.value) return
  try {
    if (reverseServiceDown) {
      locationPreview.value = formatLatLng(geo.value)
      locationInfo.value = { province: '', city: '', district: '', address: locationPreview.value }
      return
    }
    console.log('[Publish] 开始逆地址解析', geo.value)
    const resp: any = await request({
      url: '/xiangsu/location/reverse/',
      method: 'get',
      params: { lat: geo.value.lat, lng: geo.value.lng }
    })
    console.log('[Publish] 逆地址解析响应', resp)
    if (resp?.success && resp?.data) {
      locationPreview.value = formatAddress(resp.data)
      const ad = resp.data?.ad_info || {}
      locationInfo.value = {
        province: ad.province,
        city: ad.city,
        district: ad.district,
        address: resp.data?.address
      }
      console.log('[Publish] 逆地址解析成功', locationPreview.value, locationInfo.value)
    } else {
      console.warn('[Publish] 逆地址解析失败', resp)
      locationPreview.value = formatLatLng(geo.value)
      locationInfo.value = { province: '', city: '', district: '', address: locationPreview.value }
      reverseServiceDown = true
    }
  } catch (error) {
    console.error('[Publish] 逆地址解析异常', error)
    locationPreview.value = formatLatLng(geo.value)
    locationInfo.value = { province: '', city: '', district: '', address: locationPreview.value }
    reverseServiceDown = true
  }
}

const onToggleLocation = () => {
  if (showLocation.value) {
    reverseGeocode()
  } else {
    locationPreview.value = ''
    locationInfo.value = null
  }
}

watch(showLocation, (val) => {
  if (val && geo.value) reverseGeocode()
})

const formatAddress = (data: any): string => {
  const ad = data?.ad_info || {}
  const fa = data?.formatted_addresses || {}
  const addr = data?.address || ''
  const parts = [ad.province, ad.city, ad.district].filter(Boolean)
  const tail = fa.recommend || fa.rough || addr || ''
  return parts.length ? `${parts.join(' ')} ${tail}`.trim() : tail
}

const formatLatLng = (g: { lat: number; lng: number } | null): string => {
  if (!g) return ''
  const lat = Number(g.lat).toFixed(4)
  const lng = Number(g.lng).toFixed(4)
  return `${lat}, ${lng}`
}


// 发布动态
const publishPost = async () => {
  console.log('[Publish] 开始发布动态', postContent.value)
  
  // 允许纯图片发布
  if (!postContent.value.trim() && imageFiles.value.length === 0) {
    showMessage('请输入动态内容或上传图片','error')
    console.log('[Publish] 内容和图片都为空')
    return
  }
  
  // 如果正在上传中，不允许重复点击发布
  if (isUploading.value) {
    showMessage('图片上传中，请稍候...','error')
    return
  }
  
  try {
    // 如果有图片，先上传图片
    let imageUrls: string[] = []
    if (imageFiles.value.length > 0) {
      imageUrls = await uploadImages()
      console.log('[Publish] 上传的图片URLs', imageUrls)
      
      // 检查是否所有图片都上传成功
      if (imageUrls.length !== imageFiles.value.length) {
        console.warn('[Publish] 部分图片上传失败，实际上传:', imageUrls.length, '张，总图片数:', imageFiles.value.length)
        // 即使部分失败也继续，不阻断流程
      }
    }
    
    // 发布动态
    const postData: any = { content: postContent.value }
    if (imageUrls.length > 0) {
      postData.image_urls = imageUrls
    }
    
    // 添加位置信息
    if (showLocation.value && geo.value) {
      postData.lat = geo.value.lat
      postData.lng = geo.value.lng
    }
    if (showLocation.value && locationInfo.value) {
      postData.city = locationInfo.value.city
      postData.province = locationInfo.value.province
      postData.nation = locationInfo.value.nation
    }
    
    // 添加标签
    if (selectedTags.value.length > 0) {
      postData.tags = selectedTags.value
    }
    
    const response = await createPost(postData)
    console.log('[Publish] 发布动态成功', response)
    
    // 检查响应状态
    if (response && typeof response === 'object' && 'code' in response && (response.code === 200 || response.code === 201)) {
      showMessage('发布成功','success')
      triggerPointsToast?.(5)
      if (props.asModal) {
        emit('published')
      } else {
        router.push('/community')
      }
    } else {
      showMessage('发布失败，请重试','error')
    }
  } catch (error) {
    console.error('[Publish] 发布失败:', error)
    const errorMessage = error instanceof Error ? error.message : '发布失败'
    showMessage(`发布失败: ${errorMessage}`,'error')
  }
}

const polishContent = async () => {
  if (!postContent.value.trim()) {
    showMessage('请输入要润色的内容','error')
    return
  }
  try {
    polishing.value = true
    const resp: any = await polishPostText({ text: postContent.value })
    const t = (resp && typeof resp === 'object')
      ? (resp.data?.text ?? resp.text ?? resp.data?.data?.text)
      : undefined
    if (typeof t === 'string' && t.trim()) {
      postContent.value = t.trim()
      const msg = resp?.message
      if (typeof msg === 'string' && /未配置|失败/.test(msg)) {
        console.warn('[Publish] AI未配置或失败，已使用原文/退化结果')
      }
    } else {
      showMessage('润色失败，请稍后重试','error')
    }
  } catch (e) {
    console.error('[Publish] AI润色失败', e)
    showMessage('润色失败，请稍后重试','error')
  } finally {
    polishing.value = false
  }
}



// 处理地点选择
const handleLocationSelect = (location: any) => {
  console.log('[Publish] 选择地点', location)
  selectedLocation.value = location
  
  // 自动开启位置显示
  showLocation.value = true
  
  // 更新geo坐标并获取地址信息
  if (location.lat && location.lng) {
    geo.value = { lat: location.lat, lng: location.lng }
    // 异步获取地址信息
    reverseGeocode()
  } else {
    // 如果没有坐标，使用地址作为位置信息
    locationPreview.value = location.address || location.name
    locationInfo.value = {
      province: '',
      city: '',
      district: '',
      address: location.address || location.name
    }
  }
  
  // 更新帖子内容，添加地点标签
  const contentWithoutLocation = removeLocationTag(postContent.value)
  postContent.value = addLocationTag(contentWithoutLocation, location)
}

// 移除地点
const removeLocation = () => {
  console.log('[Publish] 移除地点')
  selectedLocation.value = null
  locationPreview.value = ''
  locationInfo.value = null
  postContent.value = removeLocationTag(postContent.value)
  showLocation.value = false
}

const showLocationPicker = ref(false)
const selectedLocation = ref<any | null>(null)

// 取消发布
const cancelPublish = () => {
  console.log('[Publish] 取消发布')
  // 如果有未保存的内容，显示确认对话框
  if (postContent.value.trim() || imagePreviews.value.length > 0) {
    showConfirm('确定要取消发布吗？未保存的内容将丢失。').then(ok => {
      if (!ok) return
      if (props.asModal) emit('close')
      else router.back()
    })
  } else {
    // 没有内容直接返回
    if (props.asModal) emit('close')
    else router.back()
  }
}

const showConfirm = (text: string): Promise<boolean> => {
  return new Promise(resolve => {
    const overlay = document.createElement('div')
    overlay.setAttribute('style', 'position:fixed;inset:0;background:rgba(0,0,0,0.35);z-index:9998')
    const modal = document.createElement('div')
    modal.setAttribute('style', 'position:fixed;left:50%;top:40%;transform:translate(-50%,-50%);min-width:280px;padding:18px 16px;border-radius:12px;background:#222;color:#fff;box-shadow:0 10px 30px rgba(0,0,0,0.3);z-index:9999')
    const msg = document.createElement('div')
    msg.textContent = text
    msg.setAttribute('style', 'font-size:14px;margin-bottom:14px')
    const btns = document.createElement('div')
    btns.setAttribute('style', 'display:flex;gap:10px;justify-content:flex-end')
    const ok = document.createElement('button')
    ok.textContent = '确定'
    ok.setAttribute('style', 'padding:6px 12px;border:none;background:#2E8B57;color:#fff;border-radius:8px;cursor:pointer')
    const cancel = document.createElement('button')
    cancel.textContent = '取消'
    cancel.setAttribute('style', 'padding:6px 12px;border:none;background:#555;color:#fff;border-radius:8px;cursor:pointer')
    ok.onclick = () => { modal.remove(); overlay.remove(); resolve(true) }
    cancel.onclick = () => { modal.remove(); overlay.remove(); resolve(false) }
    btns.appendChild(cancel); btns.appendChild(ok)
    modal.appendChild(msg); modal.appendChild(btns)
    document.body.appendChild(overlay)
    document.body.appendChild(modal)
  })
}

// 在组件挂载时检查路由参数
onMounted(() => {
  console.log('[Publish] 组件挂载')
  getBrowserLocation()
  loadTags()
  // 如果有传递的内容参数，设置到文本框中
  if (route.query.content) {
    postContent.value = route.query.content as string
    console.log('[Publish] 从路由参数设置内容', postContent.value)
  }
  
  // 如果有传递的类型参数，可以用于预设话题标签等
  if (route.query.type) {
    const type = route.query.type as string
    console.log('[Publish] 从路由参数设置类型', type)
    // 可以根据类型添加相应的话题标签
    if (!postContent.value.includes('#')) {
      postContent.value += ` #${type}`
    }
  }
})
</script>

<style scoped>
.publish {
  padding: 20px;
  width: 100%;
  box-sizing: border-box;
}

.page-header {
  margin-bottom: 30px;
  padding: 20px;
  background: white;
  border-radius: 15px;
  box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
  box-sizing: border-box;
}

.header-top {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.header-actions {
  display: flex;
  align-items: center;
}

.page-header h1 {
  font-size: 2rem;
  margin: 0;
  color: #2c3e50;
  flex: 1;
  text-align: center;
}

.back-btn, .cancel-btn, .publish-btn {
  padding: 10px 20px;
  border: none;
  border-radius: 20px;
  font-weight: bold;
  cursor: pointer;
  transition: all 0.3s;
  white-space: nowrap;
}

.back-btn {
  background-color: #f8f9fa;
  color: #495057;
}

.back-btn:hover {
  background-color: #e9ecef;
}

.cancel-btn {
  background-color: #f8f9fa;
  color: #6c757d;
  margin-right: 10px;
}

.cancel-btn:hover {
  background-color: #e9ecef;
  color: #495057;
}

.publish-btn {
  background-color: #42b983;
  color: white;
}

.publish-btn:hover:not(:disabled) {
  background-color: #359c6d;
  transform: scale(1.05);
}

.publish-btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
  transform: none;
}

.publish-content {
  max-width: 800px;
  margin: 0 auto;
}

.publish-card {
  background: white;
  border-radius: 15px;
  box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
  padding: 30px;
  box-sizing: border-box;
}

.user-section {
  display: flex;
  align-items: center;
  margin-bottom: 30px;
  padding-bottom: 20px;
  border-bottom: 1px solid #eee;
}

.user-avatar {
  font-size: 3rem;
  margin-right: 20px;
}

.user-info h3 {
  margin: 0 0 5px 0;
  color: #2c3e50;
}

.user-info p {
  margin: 0;
  color: #7f8c8d;
}

.editor-section {
  margin-bottom: 30px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.content-input {
  width: 100%;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 15px;
  font-size: 1rem;
  font-family: inherit;
  resize: vertical;
  box-sizing: border-box;
  margin-bottom: 20px;
}

.content-input:focus {
  outline: none;
  border-color: #42b983;
}

.image-upload-section {
  margin-top: 20px;
}

/* 上传进度条样式 */
.upload-progress-container {
  margin-bottom: 15px;
  padding: 10px;
  background-color: #f9f9f9;
  border-radius: 8px;
}

.progress-bar {
  width: 100%;
  height: 8px;
  background-color: #e0e0e0;
  border-radius: 4px;
  overflow: hidden;
  margin-bottom: 5px;
}

.progress-fill {
  height: 100%;
  background-color: #42b983;
  transition: width 0.3s ease;
  border-radius: 4px;
}

.progress-text {
  font-size: 0.9rem;
  color: #666;
  text-align: right;
  display: block;
}

.image-preview {
  display: grid;
  grid-template-columns: repeat(3, 180px);
  gap: 8px;
  justify-content: center;
  margin-bottom: 20px;
}

.preview-item {
  position: relative;
  border-radius: 10px;
  overflow: hidden;
  aspect-ratio: 1;
}

.preview-item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.remove-btn {
  position: absolute;
  top: 5px;
  right: 5px;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background-color: rgba(0, 0, 0, 0.5);
  color: white;
  border: none;
  cursor: pointer;
  font-size: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.image-upload {
  border: 2px dashed #dee2e6;
  border-radius: 15px;
  padding: 40px 20px;
  text-align: center;
  cursor: pointer;
  transition: all 0.3s;
}

.image-upload:hover {
  border-color: #42b983;
  background-color: #f8f9fa;
}

.upload-placeholder {
  border: 2px dashed #dee2e6;
  border-radius: 15px;
  padding: 40px 20px;
  text-align: center;
  cursor: pointer;
  transition: all 0.3s;
}

.upload-placeholder:hover {
  border-color: #42b983;
  background-color: #f8f9fa;
}

.upload-icon {
  font-size: 3rem;
  margin-bottom: 15px;
  display: block;
}

.image-upload p {
  margin: 0;
  color: #7f8c8d;
  font-size: 1.1rem;
}

.ai-assistant {
  margin-bottom: 30px;
  text-align: center;
}

.ai-btn {
  padding: 15px 30px;
  background-color: #e9f7ef;
  color: #42b983;
  border: none;
  border-radius: 30px;
  font-weight: bold;
  cursor: pointer;
  transition: all 0.3s;
  display: inline-flex;
  align-items: center;
  gap: 10px;
}

.ai-btn:hover {
  background-color: #42b983;
  color: white;
  transform: scale(1.05);
}

.ai-icon {
  font-size: 1.5rem;
}

.ai-suggestions {
  margin-top: 20px;
  text-align: left;
}

.ai-suggestions h3 {
  color: #2c3e50;
  margin-bottom: 15px;
}

.location-preview {
  display: flex;
  align-items: center;
  padding: 12px 16px;
  background-color: #f0f8ff;
  border: 1px solid #e6f3ff;
  border-radius: 8px;
  margin-bottom: 20px;
}

.location-icon {
  margin-right: 8px;
  font-size: 16px;
}

.location-text {
  flex: 1;
  color: #333;
  font-size: 14px;
}

.remove-location-btn {
  background: none;
  border: none;
  color: #999;
  font-size: 18px;
  cursor: pointer;
  padding: 4px;
  border-radius: 50%;
  width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s;
}

.remove-location-btn:hover {
  background-color: #e6f3ff;
  color: #666;
}

.suggestions-list {
  display: flex;
  flex-direction: column;
  gap: 15px;
  margin-bottom: 20px;
}

.suggestion-item {
  padding: 15px;
  background-color: #f8f9fa;
  border-radius: 10px;
  border: 1px solid #dee2e6;
  cursor: pointer;
  transition: all 0.3s;
}

.suggestion-item:hover {
  background-color: #e9f7ef;
  border-color: #42b983;
}

.regenerate-btn {
  padding: 10px 20px;
  background-color: #42b983;
  color: white;
  border: none;
  border-radius: 20px;
  cursor: pointer;
  transition: all 0.3s;
}

.regenerate-btn:hover {
  background-color: #359c6d;
  transform: scale(1.05);
}

.additional-options {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 20px;
}

.option-item {
  display: flex;
  align-items: center;
  gap: 10px;
}

.switch {
  position: relative;
  display: inline-block;
  width: 50px;
  height: 24px;
}

.switch input {
  opacity: 0;
  width: 0;
  height: 0;
}

.slider {
  position: absolute;
  cursor: pointer;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: #ccc;
  transition: .4s;
  border-radius: 24px;
}

.slider:before {
  position: absolute;
  content: "";
  height: 16px;
  width: 16px;
  left: 4px;
  bottom: 4px;
  background-color: white;
  transition: .4s;
  border-radius: 50%;
}

input:checked + .slider {
  background-color: #42b983;
}

input:checked + .slider:before {
  transform: translateX(26px);
}

.option-label {
  color: #495057;
  font-weight: 500;
}

  
  /* 地点标签样式 */
  .location-tags-container {
    margin-top: 16px;
    padding: 12px;
    background: #f5f9ff;
    border-radius: 8px;
    border: 1px solid #e3f2fd;
  }
  
  .location-tag {
    display: inline-flex;
    align-items: center;
    padding: 6px 12px;
    background: #e3f2fd;
    border-radius: 16px;
    font-size: 14px;
    color: #1976D2;
    max-width: 100%;
    overflow: hidden;
  }
  
  .location-tag-icon {
    margin-right: 6px;
    font-size: 16px;
  }
  
  .location-tag-text {
    flex: 1;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  
  .location-tag-remove {
    margin-left: 8px;
    background: none;
    border: none;
    color: #999;
    font-size: 18px;
    cursor: pointer;
    padding: 0;
    width: 20px;
    height: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    transition: all 0.2s;
  }
  
  .location-tag-remove:hover {
    background: rgba(0,0,0,0.1);
    color: #333;
  }
  
  .topic-btn {
    background-color: #f8f9fa;
    color: #495057;
    border: 1px solid #dee2e6;
  border-radius: 20px;
  cursor: pointer;
  transition: all 0.3s;
}

.topic-btn:hover {
  background-color: #42b983;
  color: white;
  border-color: #42b983;
}



@media (max-width: 768px) {
  .publish {
    padding: 15px;
  }
  
  .publish-card {
    padding: 20px;
  }
  
  .page-header h1 {
    font-size: 1.8rem;
  }
  
  .additional-options {
    flex-direction: column;
    align-items: flex-start;
  }
  
  .content-input {
    padding: 15px;
  }
  
  .ai-btn {
    padding: 12px 25px;
  }
  
  .image-preview {
    grid-template-columns: repeat(2, 1fr);
  }
  
  .tag-input {
    flex-direction: column;
  }
  
  .tag-input button {
    align-self: flex-start;
  }
}

@media (max-width: 480px) {
  .header-top {
    flex-direction: column;
    gap: 15px;
  }
  
  .page-header h1 {
    font-size: 1.5rem;
  }
  
  .back-btn, .cancel-btn, .publish-btn {
    padding: 8px 12px;
    font-size: 0.85rem;
  }
  
  .header-actions {
    gap: 5px;
  }
  
  .cancel-btn {
    margin-right: 5px;
  }
  
  .user-avatar {
    font-size: 2.5rem;
  }
  
  .image-upload {
    padding: 30px 15px;
  }
  
  .upload-icon {
    font-size: 2.5rem;
  }
  
  .ai-btn {
    padding: 10px 20px;
    font-size: 0.9rem;
  }
  
  .image-preview {
    grid-template-columns: 1fr;
  }
}
.input-toolbar {
  margin-top: 10px;
}

.ai-polish-btn {
  padding: 10px 20px;
  background-color: #42b983;
  color: white;
  border: none;
  border-radius: 20px;
  cursor: pointer;
}

.ai-polish-btn[disabled] {
  opacity: 0.6;
  cursor: not-allowed;
}

/* 悬浮窗底部工具栏样式（仅 asModal 时显示） */
.modal-toolbar {
  position: sticky;
  bottom: 0;
  left: 0;
  right: 0;
  height: 56px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 16px;
  background: #fff;
  border-top: 1px solid #eee;
}
.tool-btn {
  width: 36px;
  height: 36px;
  border: none;
  border-radius: 8px;
  background: transparent;
  color: #666;
  margin-right: 8px;
  cursor: pointer;
  transition: color 0.2s ease;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.tool-btn:hover { color: #4CAF50; }

.ai-text-btn {
  padding: 8px 12px;
  border: none;
  background: linear-gradient(90deg, #43A047 0%, #66BB6A 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  font-weight: 600;
  cursor: pointer;
}

.toolbar-right { display: inline-flex; align-items: center; gap: 10px; }
.char-count { font-size: 12px; color: #999; }
.modal-publish {
  padding: 8px 18px;
  height: 36px;
  background: #4CAF50;
  color: #fff;
  border: none;
  border-radius: 20px;
  box-shadow: 0 6px 16px rgba(76, 175, 80, 0.3);
  cursor: pointer;
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.modal-publish:hover { transform: translateY(-1px); box-shadow: 0 8px 20px rgba(76,175,80,0.35); }

/* 极简卡片（弹窗内） */
.publish-card.minimal {
  box-shadow: none;
  border-radius: 0;
  padding: 16px 16px 8px 16px;
  background: #fff;
}

/* 九宫格图片上传区 */
.image-grid {
  display: grid;
  grid-template-columns: repeat(3, 100px);
  gap: 10px;
}
.grid-item {
  position: relative;
  width: 100px;
  height: 100px;
  border-radius: 12px;
  overflow: hidden;
}
.grid-item img { width: 100%; height: 100%; object-fit: cover; }
.remove-badge {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: none;
  background: rgba(0,0,0,0.5);
  color: #fff;
  cursor: pointer;
}
.upload-tile {
  width: 100px;
  height: 100px;
  border-radius: 12px;
  background: #F5F7FA;
  border: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
.modal-cancel {
  height: 36px;
  margin-right: 8px;
  padding: 0 12px;
  border: none;
  border-radius: 8px;
  background: #f5f5f5;
  color: #333;
  cursor: pointer;
}
</style>
